\input texinfo @c -*- texinfo -*-
@c shepherd.texi -- The documentation in Texinfo format.
@documentencoding UTF-8
@setfilename shepherd.info
@settitle The GNU Shepherd Manual

@include version.texi
@set OLD-YEARS 2002, 2003
@set NEW-YEARS 2013, 2016, 2018, 2019, 2020

@copying
Copyright @copyright{} @value{OLD-YEARS} Wolfgang J@"ahrling@*
Copyright @copyright{} @value{NEW-YEARS} Ludovic Courtès@*
Copyright @copyright{} 2020 Brice Waegeneire@*
Copyright @copyright{} 2020 Oleg Pykhalov
Copyright @copyright{} 2020 Jan (janneke) Nieuwenhuizen@*

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
copy of the license is included in the section entitled ``GNU Free
Documentation License''.
@end copying

@dircategory System software
@direntry
* shepherd: (shepherd). The Shepherd service manager.
* herd: (shepherd)Invoking herd
                        Controlling the Shepherd service manager.
* reboot: (shepherd)Invoking reboot
                        Rebooting a Shepherd-controlled system.
* halt: (shepherd)Invoking halt
                        Turning off a Shepherd-controlled system.
@end direntry

@titlepage
@title The GNU Shepherd Manual
@subtitle For use with the GNU Shepherd @value{VERSION}
@subtitle Last updated @value{UPDATED}

@author Wolfgang J@"ahrling
@author Ludovic Courtès

@insertcopying
@end titlepage

@contents


@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@ifnottex
@node Top
@top The GNU Shepherd Manual

This manual documents the GNU@tie{}Shepherd version @value{VERSION}, a
service manager for the GNU system.

@menu
* Introduction::      Introduction to the Shepherd service manager.
* Jump Start::        How to do simple things with the Shepherd.
* herd and shepherd:: User interface to service management.
* Services::          Details on services.
* Misc Facilities::   Generally useful things provided by the Shepherd.
* Internals::         Hacking shepherd.

* GNU Free Documentation License::  The license of this manual.
* Concept Index::
* Procedure and Macro Index::
* Variable Index::
* Type Index::
@end menu
@end ifnottex

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Introduction
@chapter Introduction

@cindex service manager
This manual documents the GNU@tie{}Daemon Shepherd, or GNU@tie{}Shepherd
for short.  The Shepherd looks after system services, typically @dfn{daemons}.
It is used to start and stop them in a reliable
fashion.  For instance it will dynamically determine and start any
other services that our desired service depends upon.  As another
example, the Shepherd might detect conflicts among services.  In this
situation it would simply prevent the conflicting services from
running concurrently.

The Shepherd is the @dfn{init system} of the GNU operating system---it is the
first user process that gets started, typically with PID 1, and runs
as @code{root}.  Normally the purpose of init systems is to manage all
system-wide services, but the Shepherd can also be a useful tool assisting
unprivileged users in the management of their own daemons.

Flexible software requires some time to master and
the Shepherd is no different.  But don't worry: this manual should allow you to
get started quickly.  Its first chapter is designed as a practical
introduction to the Shepherd and should be all you need for everyday use
(@pxref{Jump Start}).  In chapter two we will describe the
@command{herd} and @command{shepherd} programs, and their relationship, in
more detail (@ref{herd and shepherd}).  Subsequent chapters provide a full
reference manual and plenty of examples, covering all of Shepherd's
capabilities.  Finally, the last chapter provides information for
those souls brave enough to hack the Shepherd itself.

@cindex dmd
The Shepherd was formerly known as ``dmd'', which stands for @dfn{Daemon
Managing Daemons} (or @dfn{Daemons-Managing Daemon}?).

@cindex Guile
@cindex Scheme
@cindex GOOPS
This program is written in Guile, an implementation of the
Scheme programming language, using the GOOPS extension for
object-orientation.  Guile is also the Shepherd's configuration language.
@xref{Introduction,,, guile, GNU Guile Reference Manual}, for an
introduction to Guile.  We have tried to
make the Shepherd's basic features as accessible as possible---you should be
able to use these even if you do not know how to program in Scheme.  A
basic grasp of Guile and GOOPS is required only if you wish to make
use of the Shepherd's more advanced features.

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Jump Start
@chapter Jump Start

@cindex prefix
This chapter gives a short overview of the Shepherd.  It is enough if you just
need the basic features of it.  As it is not assumed that readers are
familiar with all the involved issues, a very experienced user might
be annoyed by the often very detailed descriptions in this
introduction.  Those users are encouraged to just skip to the
reference section.

Note that all the full file names in the following text are based on
the assumption that you have installed the Shepherd with an empty prefix.  If
your Shepherd installation for example resides in @code{/usr/local}
instead, add this directory name in front of the absolute file names
mentioned below.

@cindex Configuration file
When @command{shepherd} gets started, it reads and evaluates a
configuration file.  When it is started with superuser privileges, it
tries to use @code{/etc/shepherd.scm}.  When started as normal user, it
looks for a file called @code{$XDG_CONFIG_HOME/shepherd/init.scm}.  If
the @code{XDG_CONFIG_HOME} environment variable is not defined,
@code{$HOME/.config/shepherd/init.scm} is used instead (@pxref{Managing
User Services }).  With the option @code{--config} (or, for short,
@code{-c}), you can specify where to look instead.  So if you want to
start @command{shepherd} with an alternative file, use one of the
following commands:

@example
shepherd --config=/etc/shepherd.scm.old
shepherd -c /etc/shepherd.scm.old
@end example

@cindex Starting a service
As the final ``d'' suggests, @command{shepherd} is just
a daemon that (usually) runs in the
background, so you will not interact with it directly.  After it is
started, @command{shepherd} will listen on a socket special file, usually
@code{/var/run/shepherd/socket}, for further commands.  You use the tool
@dfn{herd} to send these commands to @command{shepherd}.  Usage of herd is simple and
straightforward: To start a service called @code{apache}, you use:

@example
herd start apache
@end example

@cindex Status (of services)
@cindex Service status
When you do this, all its dependencies will get resolved.  For
example, a webserver is quite likely to depend on working networking,
thus it will depend on a service called @code{networking}.  So if you
want to start @code{apache}, and @code{networking} is not yet running, it
will automatically be started as well.  The current status of all the
services defined in the configuration file can be queried like this:

@example
herd status
@end example

@noindent
Or, to get additional details about each service, run:

@example
herd detailed-status
@end example

@noindent
In this example, this would show the @code{networking} and @code{apache}
services as started.  If you just want to know the status of the
@code{apache} service, run:

@example
herd status apache
@end example

@cindex Stopping a service
You can stop
a service and all the services that depend on it will be stopped.
Using the example above, if you stop @code{networking}, the service
@code{apache} will be stopped as well---which makes perfect sense,
as it cannot work without the network being up.  To actually stop a
service, you use the following, probably not very surprising, command:

@example
herd stop networking
@end example

There are two more actions you can perform on every service: the
actions @code{enable} and @code{disable} are used to prevent and allow
starting of the particular service.  If a service is intended to be
restarted whenever it terminates (how this can be done will not be
covered in this introduction), but it is respawning too often in a
short period of time (by default 5 times in 5 seconds), it will
automatically be disabled.  After you have fixed the problem that
caused it from being respawned too fast, you can start it again with
the commands:

@example
herd enable foo
herd start foo
@end example

@cindex virtual services
@cindex fallback services
But there is far more you can do than just that.  Services can not
only simply depend on other services, they can also depend on
@emph{virtual} services.  A virtual service is a service that is
provided by one or more service additionally.  For instance, a service
called @code{exim} might provide the virtual service
@code{mailer-daemon}.  That could as well be provided by a service
called @code{smail}, as both are mailer-daemons.  If a service needs
any mailer-daemon, no matter which one, it can just depend on
@code{mailer-daemon}, and one of those who provide it gets started (if
none is running yet) when resolving dependencies.  The nice thing is
that, if trying to start one of them fails, @command{shepherd} will go on and try to
start the next one, so you can also use virtual services for
specifying @emph{fallbacks}.

Additionally to all that, you can perform service-specific actions.
Coming back to our original example, @code{apache} is able to
reload its modules, therefore the action @code{reload-modules} might
be available:

@example
herd reload-modules apache
@end example

Service-specific actions can only be used when the service is
started, i.e. the only thing you can do to a stopped service is
starting it.  An exception exists, see below.  (If you may at some
point find this too restrictive because you want to use variants of
the same service which are started in different ways, consider using
different services for those variants instead, which all provide the
same virtual service and thus conflict with each other, if this is
desired.  That's one of the reasons why virtual services exist, after
all.)

There are two actions which are special, because even if services
can implement them on their own, a default implementation is provided
by @command{shepherd} (another reason why they are special is that the default
implementations can be called even when the service is not running;
this inconsistency is just to make it more intuitive to get
information about the status of a service, see below).

These actions are @code{restart} and @code{status}.  The default
implementation of @code{restart} calls @code{stop} and @code{start} on the
affected service, taking care to also restart any dependent services. The
default implementation of @code{status} displays some general information
about the service, like what it provides, what it depends on and with which
other services it conflicts (because they provide a virtual service that is
also provided by that particular service).

A special service is @code{root}, which is used for controlling the
Shepherd itself.  You can also reference to this service as
@code{shepherd}.  It implements various actions.  For example, the
@code{status} action displays which services are started and which ones
are stopped, whereas @code{detailed-status} has the effect of applying
the default implementation of @code{status} to all services one after
another.  The @code{load} action is unusual insofar as it shows a
feature that is actually available to all services, but which we have
not seen yet: It takes an additional argument.  You can use @code{load}
to load arbitrary code into the Shepherd at runtime, like this:

@example
herd load shepherd ~/additional-services.scm
@end example

In the same vein the special action @code{doc} describes its service
when called without an argument or describes a service-specific action
when called with the action as the additional arguments.  You can even
get the list of the service-specific actions a service provides when
using with the additional argument @code{list-actions}.
@example
$ herd doc root
The root service is used to operate on shepherd itself.
$ herd doc root list-actions
root (help status halt power-off load eval unload reload daemonize persistency no-persistency cd restart)
$ herd doc root action power-off
power-off: Halt the system and turn it off.
@end example

This is enough now about the @command{herd} and @command{shepherd} programs, we
will now take a look at how to configure the Shepherd.  In the configuration
file, we need mainly the definition of services.  We can also do
various other things there, like starting a few services already.

FIXME: Finish.  For now, look at the @code{doc/examples/} subdirectory.

@example
...
@end example

Ok, to summarize:

@itemize @bullet
@item
@command{shepherd} is a daemon, @command{herd} the program that controls it.
@item
You can start, stop, restart, enable and disable every service, as
well as display its status.
@item
You can perform additional service-specific actions, which you can
also list.
@item
Actions can have arguments.
@item
You can display the status of a service, even if the service does not
provide a specific implementation for this action.  The same is true
for restarting.
@item
The @code{root}/@code{shepherd} service is used to control
@command{shepherd} itself.
@end itemize

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node herd and shepherd
@chapter @command{herd} and @command{shepherd}

@cindex herd
@cindex shepherd
@cindex daemon
@cindex daemon controller
@cindex relative file names
@cindex herding, of daemons
The daemon that runs in the background and is responsible for
controlling the services is @command{shepherd}, while the user interface
tool is called @command{herd}: it's the command that allows you to
actually @emph{herd} your daemons@footnote{
@cindex deco, daemon controller
In the past, when the
GNU@tie{}Shepherd was known as GNU@tie{}dmd, the @command{herd} command
was called @code{deco}, for @dfn{DaEmon COntroller}.}.  To perform an
action, like stopping a service or calling an action of a service, you
use the herd program.  It will communicate with shepherd over a Unix
Domain Socket.

Thus, you start @command{shepherd} once, and then always use herd whenever you want
to do something service-related.  Since herd passes its current
working directory to @command{shepherd}, you can pass relative file names without
trouble.  Both @command{shepherd} and herd understand the standard arguments
@code{--help}, @code{--version} and @code{--usage}.


@menu
* Invoking shepherd::           How to start the service damon.
* Invoking herd::               Controlling daemons.
* Invoking reboot::             Rebooting a shepherd-controlled system.
* Invoking halt::               Turning off a shepherd-controlled system.
@end menu

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Invoking shepherd
@section Invoking @command{shepherd}

@cindex @command{shepherd} Invocation
@cindex invoking @command{shepherd}
The @code{shepherd} program has the following synopsis:

@example
shepherd [@var{option}@dots{}]
@end example

It accepts the following options:

@table @samp
@item -c @var{file}
@itemx --config=@var{file}
Read and evaluate @var{file} as the configuration script on startup.

@var{file} is evaluated in the context of a fresh module where bindings
from the @code{(shepherd service)} module and Guile's @code{(oop goops)} are
available, in addition to the default set of Guile bindings.  In
particular, this means that code in @var{file} may use
@code{register-services}, the @code{<service>} class, and related tools
(@pxref{Services}).

@item -I
@itemx --insecure
@cindex security
@cindex insecure
Do not check if the directory where the socket---our communication
rendez-vous with @command{herd}---is located has permissions @code{700}.
If this option is not specified, @command{shepherd} will abort if the
permissions are not as expected.

@item -l [@var{file}]
@itemx --logfile[=@var{file}]
@cindex logging
@cindex log file
Log output into @var{file}.

For unprivileged users, the default log file is
@file{$XDG_DATA_DIR/.local/share/shepherd/shepherd.log}.

@cindex syslog
When running as root, the default behavior is to connect to
@file{/dev/log}, the @dfn{syslog} socket (@pxref{Overview of Syslog,,,
libc, The GNU C Library Reference Manual}).  A syslog daemon,
@command{syslogd}, is expected to read messages from there
(@pxref{syslogd invocation, syslogd,, libc, GNU Inetutils}).

When @file{/dev/log} is unavailable, for instance because
@command{syslogd} is not running, as is the case during system startup
and shutdown, @command{shepherd} falls back to the Linux kernel
@dfn{ring buffer}, @file{/dev/kmsg}.  If @file{/dev/kmsg} is missing, as
is the case on other operating systems, it falls back to
@file{/dev/console}.

@item --pid[=@var{file}]
When @command{shepherd} is ready to accept connections, write its PID to @var{file} or
to the standard output if @var{file} is omitted.

@item -p [@var{file}]
@itemx --persistency[=@var{file}]
@c FIXME-CRITICAL

@item -s @var{file}
@itemx --socket=@var{file}
@cindex socket special file
@vindex XDG_RUNTIME_DIR
Receive further commands on the socket special file @var{file}.  If this
option is not specified, @file{@var{localstatedir}/run/shepherd/socket} is
taken when running as @code{root}; when running as an unprivileged
user, @command{shepherd} listens to @file{/run/user/@var{uid}/shepherd/socket},
where @var{uid} is the user's numerical ID@footnote{On GNU/Linux, the
@file{/run/user/@var{uid}} directory is typically created by elogind or by
systemd, which are available in most distributions.}, or to
@file{$XDG_RUNTIME_DIR/shepherd} when the @code{XDG_RUNTIME_DIR}
environment variable is defined.

If @code{-} is specified as file name, commands will be read from
standard input, one per line, as would be passed on a @command{herd}
command line (@pxref{Invoking herd}).

@item --quiet
Synonym for @code{--silent}.

@end table

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Invoking herd
@section Invoking @command{herd}

@cindex herd
The @command{herd} command is a generic client program to control a
running instance of @command{shepherd} (@pxref{Invoking shepherd}).  It has the
following synopsis:

@example
herd [@var{option}@dots{}] @var{action} [@var{service} [@var{arg}@dots{}]]
@end example

It causes the @var{action} of the @var{service} to be invoked.  When
@var{service} is omitted and @var{action} is @code{status} or
@code{detailed-status}, the @code{root} service is used@footnote{This
shorthand does not work for other actions such as @code{stop}, because
inadvertently typing @code{herd stop} would stop all the services, which
could be pretty annoying.} (@pxref{The root and unknown services}, for
more information on the @code{root} service.)

For each action, you should pass the appropriate @var{arg}s.  Actions
that are available for every service are @code{start}, @code{stop},
@code{restart}, @code{status}, @code{enable}, @code{disable}, and
@code{doc}.

If you pass a file name as an @var{arg}, it will be passed as-is to
the Shepherd, thus if it is not an absolute name, it is local to the current
working directory of @command{shepherd}, not to herd.

The @code{herd} command understands the following option:

@table @samp

@item -s @var{file}
@itemx --socket=@var{file}
Send commands to the socket special file @var{file}. If this option is
not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken.

@end table

The @code{herd} command returns zero on success, and a non-zero exit
code on failure.  In particular, it returns a non-zero exit code when
@var{action} or @var{service} does not exist and when the given action
failed.


@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Invoking reboot
@section Invoking @command{reboot}

@cindex herd
The @command{reboot} command is a convenience client program to instruct
the Shepherd (when used as an init system) to stop all running services and
reboot the system.  It has the following synopsis:

@example
reboot [@var{option}@dots{}]
@end example

It is equivalent to running @command{herd stop shepherd}.  The
@code{reboot} command understands the following option:

@table @samp

@item -s @var{file}
@itemx --socket=@var{file}
Send commands to the socket special file @var{file}. If this option is
not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken.

@end table

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Invoking halt
@section Invoking @command{halt}

@cindex herd
The @command{halt} command is a convenience client program to instruct
the Shepherd (when used as an init system) to stop all running services and turn
off the system.  It has the following synopsis:

@example
halt [@var{option}@dots{}]
@end example

It is equivalent to running @command{herd power-off shepherd}.  As
usual, the @code{halt} command understands the following option:

@table @samp

@item -s @var{file}
@itemx --socket=@var{file}
Send commands to the socket special file @var{file}. If this option is
not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken.

@end table


@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Services
@chapter Services

@cindex service
@tindex <service>
The @dfn{service} is obviously a very important concept of the Shepherd.  On the
Guile level, a service is represented as an instance of
@code{<service>}, a GOOPS class (@pxref{GOOPS,,, guile, GNU Guile
Reference Manual}).  When creating an instance of it, you can specify
the initial values of its slots, and you actually must do this for some
of the slots.

The @code{<service>} class and its associated procedures and methods are
defined in the @code{(shepherd service)} module.

@menu
* Slots of services::            What a <service> object consists of.
* Methods of services::          What you can do with a <service> object.
* Service Convenience::          How to conveniently work with services.
* Service De- and Constructors:: Commonly used ways of starting and
                                   stopping services.
* Service Examples::             Examples that show how services are used.
* Managing User Services::       Running the Shepherd as a user.
* The root and unknown services:: Special services in the Shepherd.
@end menu

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Slots of services
@section Slots of services

@cindex <service>, slots of
@cindex slots of <service>
A service has the following slots, all of which can be initialized
with a keyword (i.e. @code{#:provides}, used when creating the object)
of the same name, except where stated otherwise.  You should not
access them directly with @code{slot-ref} or @code{slot-set!}
usually, use the methods of the service class @ref{Methods of
services} instead.

@itemize @bullet
@item
@vindex provides (slot of <service>)
@cindex canonical names of services
@code{provides} is a list of symbols that are provided by the service.
A symbol can only be provided by one service running at a time,
i.e. if two services provide the same symbol, only one of them can
run, starting the other one will fail.  Therefore, these symbols are
mainly used to denote conflicting services.  The first symbol in the
list is the canonical name for the service, thus it must be unique.
This slot has no default value and must therefore be initialized.

@item
@vindex requires (slot of <service>)
@code{requires} is, like @code{provides}, a list of symbols that
specify services.  In this case, they name what this service depends
on, i.e. before the service can be started, services that provide
those symbols must be started.  If a required symbol is provided by
several services, one will be started.  By default, this slot
contains the empty list.

@item
@vindex running (slot of <service>)
@cindex Hook for individual services
@code{running} is a hook that can be used by each service in its own
way.  The default value is @code{#f}, which indicates that the service
is not running. When an attempt is made to start the service, it will
be set to the return value of the procedure in the @code{start} slot.
It will also be passed as an argument to the procedure in the
@code{stop} slot.  If it is set a value that is an integer, it is
assumed to be a process id, and shepherd will monitor the process for
unexpected exits.  This slot can not be initialized with a keyword.

@item
@vindex respawn? (slot of <service>)
@cindex Respawning services
@code{respawn?} specifies whether the service should be respawned by
the Shepherd.  If this slot has the value @code{#t}, then assume the
@code{running} slot specifies a child process PID and restart the
service if that process terminates.  Otherwise this slot is @code{#f},
which is the default.  See also the @code{last-respawns} slot.

@item
@vindex one-shot? (slot of <service>)
@cindex one-shot services
The @code{one-shot?} slot determines whether the service is a @dfn{one-shot
service}.  A one-shot service is a service that, as soon as it has been
successfully started, is marked as ``stopped.''  Other services can
nonetheless require one-shot services.  One-shot services are useful to
trigger an action before other services are started, such as a cleanup or an
initialization action.

As for other services, the @code{start} method of a one-shot service must
return a truth value to indicate success, and false to indicate failure.

@item
@vindex start (slot of <service>)
@cindex Starting a service
@cindex Service constructor
@code{start} contains the ``constructor'' for the service, which will
be called to start the service.  (Therefore, it is not a constructor
in the sense that it initializes the slots of a @code{<service>}
object.)  This must be a procedure that accepts any amount of
arguments, which will be the additional arguments supplied by the
user.  If the starting attempt failed, it must return @code{#f}.  The
value will be stored in the @code{running} slot.  The default value is
a procedure that returns @code{#t} and performs no further actions,
therefore it is desirable to specify a different one usually.

@item
@vindex stop (slot of <service>)
@cindex Stopping a service
@cindex Service destructor
@code{stop} is, similar to @code{start}, a slot containing a
procedure.  But in this case, it gets the current value of the
@code{running} slot as first argument and the user-supplied arguments
as further arguments; it gets called to stop the service.  Its return
value will again be stored in the @code{running} slot, so that it
should return @code{#f} if it is now possible again to start the
service at a later point.  The default value is a procedure that
returns @code{#f} and performs no further actions.

@item
@vindex actions (slot of <service>)
@cindex Actions of services
@cindex Service actions
@code{actions} specifies the additional actions that can be performed
on a service when it is running.  A typical example for this is the
@code{restart} action.  The macro @code{make-actions} @ref{Service
Convenience} is provided to abstract the actual data representation
format for this slot.  (It actually is a hash currently.)

@item
@vindex enabled? (slot of <service>)
@code{enabled?} cannot be initialized with a keyword, and contains
@code{#t} by default.  When the value becomes @code{#f} at some point,
this will prevent the service from getting started.  A service can be
enabled and disabled with the methods @code{enable} and
@code{disable}, respectively @ref{Methods of services}.

@item
@vindex last-respawns (slot of <service>)
@code{last-respawns} cannot be initialized with a keyword and is only
ever used when the @code{respawn?} slot contains @code{#t}; it is a
circular list with @code{(car respawn-limit)} elements, where each
element contains the time when it was restarted, initially all 0,
later a time in seconds since the Epoch.  The first element is the one
that contains the oldest one, the last one the newest.

@item
@vindex stop-delay? (slot of <service>)
@code{stop-delay?} being false causes the @code{stop} slot to be
unused; instead, stopping the service will just cause the
@code{waiting-for-termination?} slot be set to @code{#t}.

@item
@vindex waiting-for-termination? (slot of <service>)
@code{waiting-for-termination?} cannot be initialized with a keyword
and should not be used by others, it is only used internally for
respawnable services when the @code{stop-delay?} slot contains a true
value.  @code{waiting-for-termination?} contains @code{#t} if the
service is still running, but the user requested that it be stopped,
in which case if the service terminates the next time, the respawn
handler will not start it again.

otherwise @code{#f}.

@item
@vindex replacement (slot of <service>)
@code{replacement} specifies a service to be used to replace this one
when it is stopped.  This service will continue to function normally
until the @code{stop} action is invoked.  After the service has been
successfully stopped, its definition will be replaced by the value of
this slot, which must itself be a service.  This slot is ignored if
its value is @code{#f}.

@end itemize

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Methods of services
@section Methods of services

@deffn {method} start (obj <service>)
Start the service @var{obj}, including all the services it depends on.
It tries quite hard to do this: When a service that provides a
required symbol can not be started, it will look for another service
that also provides this symbol, until starting one such service
succeeds.  There is some room for theoretical improvement here, of
course, but in practice the current strategy already works very well.
This method returns the new value of the @code{running} slot
@ref{Slots of services}, which is @code{#f} if the service could not
be started.
@end deffn

@deffn {method} stop (obj <service>)
This will stop the service @var{obj}, trying to stop services that
depend in it first, so they can be shutdown cleanly.  If this will
fail, it will continue anyway.  Stopping of services should usually
succeed, though.  Otherwise, the behaviour is very similar to the
@code{start} method.  The return value is also the new @code{running}
value, thus @code{#f} if the service was stopped.
@end deffn

@deffn {method} action (obj <service>) the-action . args
Calls the action @var{the-action} (a symbol) of the service @var{obj},
with the specified @var{args}, which have a meaning depending on the
particular action.
@end deffn

@deffn {method} conflicts-with (obj <service>)
Returns a list of the canonical names of services that conflict with
the service @var{obj}.
@end deffn

@deffn {method} canonical-name (obj <service>)
Returns the canonical name of @var{obj}, which is the first element of
the @code{provides} list.
@end deffn

@deffn {method} provided-by (obj <service>)
Returns which symbols are provided by @var{obj}.
@end deffn

@deffn {method} required-by (obj <service>)
Returns which symbols are required by @var{obj}.
@end deffn

@deffn {method} one-shot? (obj <service>)
Returns whether the service @var{obj} is a one-shot service.
@end deffn

@deffn {method} running? (obj <service>)
Returns whether the service @var{obj} is running.
@end deffn

@deffn {method} respawn? (obj <service>)
Returns whether the service @var{obj} should be respawned if it
terminates.
@end deffn

@deffn {method} default-display-status (obj <service>)
Display status information about @var{obj}.  This method is called
when the user performs the action @code{status} on @var{obj}, but
there is no specific implementation given for it.  It is also called
when @code{detailed-status} is applied on the @code{root} service.
@end deffn

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Service Convenience
@section Service Convenience

In addition to the facilities listed below, there are also some
procedures that provide commonly needed constructors and destructors
for services @ref{Service De- and Constructors}.

@deffn {procedure} register-services . services
Register all @var{services}, so that they can be taken into account
when trying to resolve dependencies.
@end deffn

@deffn {procedure} lookup-services name
Return a list of all registered services which provide the symbol
@var{name}.
@end deffn

@deffn {macro} make-actions (name proc) ...
This macro is used to create a value for the @code{actions} slot of a
service object @ref{Slots of services}.  Each @var{name} is a symbol
and each @var{proc} the corresponding procedure that will be called to
perform the action.  A @var{proc} has one argument, which will be the
current value of the @code{running} slot of the service.
@end deffn

@deffn {method} start (obj <symbol>)
Start a registered service providing @var{obj}.
@end deffn

@deffn {method} stop (obj <symbol>)
Stop a registered service providing @var{obj}.
@end deffn

@deffn {method} action (obj <symbol>) the-action . args
The same as the @code{action} method of class @code{<service>}, but
uses a service that provides @var{obj} and is running.
@end deffn

@deffn {procedure} for-each-service proc
Call @var{proc}, a procedure taking one argument, once for each
registered service.
@end deffn

@deffn {procedure} find-running services
Check if any of @var{services} is running.  If this is the case,
return its canonical name.  If not, return @code{#f}.  Only the first
one will be returned; this is because this is mainly intended to be
applied on the return value of @code{lookup-services}.
@end deffn

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Service De- and Constructors
@section Service De- and Constructors

@cindex generating constructors
@cindex generating destructors
@cindex constructors, generation of
@cindex destructors, generation of
All of the procedures listed below return procedures generated from
the supplied arguments.  These procedures take one argument in the
case of destructors and no arguments in the case of constructors.

@deffn {procedure} make-system-constructor @var{command}@dots{}
The returned procedure will execute @var{command} in a shell and
return @code{#t} if execution was successful, otherwise @code{#f}.
For convenience, it takes multiple arguments which will be
concatenated first.
@end deffn

@deffn {procedure} make-system-destructor @var{command}@dots{}
Similar to @code{make-system-constructor}, but returns @code{#f} if
execution of the @var{command} was successful, @code{#t} if not.
@end deffn

@deffn {procedure} make-forkexec-constructor @var{command} @
  [#:user #f] @
  [#:group #f] @
  [#:supplementary-groups '()] @
  [#:pid-file #f] [#:pid-file-timeout (default-pid-file-timeout)] @
  [#:log-file #f] @
  [#:directory (default-service-directory)] @
  [#:file-creation-mask #f] @
  [#:environment-variables (default-environment-variables)]
Return a procedure that forks a child process, closes all file
descriptors except the standard output and standard error descriptors,
sets the current directory to @var{directory}, sets the umask to
@var{file-creation-mask} unless it is @code{#f}, changes the environment
to @var{environment-variables} (using the @code{environ} procedure),
sets the current user to @var{user} the current group to @var{group}
unless they are @code{#f} and supplementary groups to
@var{supplementary-groups} unless they are @code{'()}, and executes
@var{command} (a list of strings.)  The result of the procedure will be
the PID of the child process.  Note that this will not work as expected
if the process ``daemonizes'' (forks); in that case, you will need to
pass @code{#:pid-file}, as explained below.

When @var{pid-file} is true, it must be the name of a PID file
associated with the process being launched; the return value is the PID
once that file has been created.  If @var{pid-file} does not show up in less
than @var{pid-file-timeout} seconds, the service is considered as failing to
start.

When @var{log-file} is true, it names the file to which the service's
standard output and standard error are redirected.  @var{log-file} is
created if it does not exist, otherwise it is appended to.
@end deffn

@deffn {procedure} make-kill-destructor [@var{signal}]
Return a procedure that sends @var{signal} to the process group of the
PID given as argument, where @var{signal} defaults to @code{SIGTERM}.

This @emph{does} work together with respawning services,
because in that case the @code{stop} method of the @code{<service>}
class sets the @code{running} slot to @code{#f} before actually
calling the destructor; if it would not do that, killing the process
in the destructor would immediately respawn the service.
@end deffn

The @code{make-forkexec-constructor} procedure builds upon the following
procedures.

@deffn {procedure} exec-command @var{command} @
  [#:user #f] @
  [#:group #f] @
  [#:supplementary-groups '()] @
  [#:log-file #f] @
  [#:directory (default-service-directory)] @
  [#:file-creation-mask #f] @
  [#:environment-variables (default-environment-variables)]
@deffnx {procedure} fork+exec-command @var{command} @
  [#:user #f] @
  [#:group #f] @
  [#:supplementary-groups '()] @
  [#:directory (default-service-directory)] @
  [#:file-creation-mask #f] @
  [#:environment-variables (default-environment-variables)]
Run @var{command} as the current process from @var{directory}, with
@var{file-creation-mask} if it's true, and with
@var{environment-variables} (a list of strings like @code{"PATH=/bin"}.)
File descriptors 1 and 2 are kept as is or redirected to @var{log-file}
if it's true, whereas file descriptor 0
(standard input) points to @file{/dev/null}; all other file descriptors
are closed prior to yielding control to @var{command}.

By default, @var{command} is run as the current user.  If the @var{user}
keyword argument is present and not false, change to @var{user}
immediately before invoking @var{command}.  @var{user} may be a string,
indicating a user name, or a number, indicating a user ID.  Likewise,
@var{command} will be run under the current group, unless the
@var{group} keyword argument is present and not false, and
@var{supplementary-groups} is not @code{'()}.

@code{fork+exec-command} does the same as @code{exec-command}, but in
a separate process whose PID it returns.
@end deffn

@defvr {Scheme Variable} default-environment-variables
This parameter (@pxref{Parameters,,, guile, GNU Guile Reference Manual})
specifies the default list of environment variables to be defined when
the procedures above create a new process.

It must be a list of strings where each string has the format
@code{@var{name}=@var{value}}.  It defaults to what @code{environ}
returns when the program starts (@pxref{Runtime Environment,
@code{environ},, guile, GNU Guile Reference Manual}).
@end defvr

@defvr {Scheme Variable} default-pid-file-timeout
This parameter (@pxref{Parameters,,, guile, GNU Guile Reference Manual})
specified the default PID file timeout in seconds, when
@code{#:pid-file} is used (see above).  It defaults to 5 seconds.
@end defvr

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Service Examples
@section Service Examples

FIXME: This needs a lot of work.

You can create a service and then register it this way:

@lisp
(define apache (make <service>
                     #:provides '(apache)
                     #:start (...)
                     #:stop (...)))
(register-services apache)
@end lisp

However, as you usually won't need a variable for the service, you can
pass it directly to @code{register-services}.  Here is an example that
also specifies some more initial values for the slots:

@lisp
(register-services
  (make <service>
        #:provides '(apache-2.0 apache httpd)
        #:requires '()
        #:start (...)
        #:stop (...)
        #:actions (make-actions
                   (reload-modules (...))
                   (restart (...)))))
@end lisp

@node Managing User Services
@section Managing User Services

The Shepherd can be used to manage services for an unprivileged user.
First, you may want to ensure it is up and running every time you log
in.  One way to accomplish that is by adding the following lines to
@file{~/.bash_profile} (@pxref{Bash Startup Files,,, bash, The GNU Bash
Reference Manual}):

@verbatim
if [[ ! -S ${XDG_RUNTIME_DIR-$HOME/.cache}/shepherd/socket ]]; then
    shepherd
fi
@end verbatim

Then, we suggest the following top-level
@file{$XDG_CONFIG_HOME/shepherd/init.scm} file, which will automatically
load individual service definitions from
@file{~/.config/shepherd/init.d}:

@lisp
(use-modules (shepherd service)
             ((ice-9 ftw) #:select (scandir)))

;; Load all the files in the directory 'init.d' with a suffix '.scm'.
(for-each
  (lambda (file)
    (load (string-append "init.d/" file)))
  (scandir (string-append (dirname (current-filename)) "/init.d")
           (lambda (file)
             (string-suffix? ".scm" file))))

;; Send shepherd into the background
(action 'shepherd 'daemonize)
@end lisp

Then, individual user services can be put in
@code{$XDG_CONFIG_HOME/shepherd/init.d/}, e.g., for @command{ssh-agent}.

@lisp
;;; Commentary:
;;;
;;; Add to your ~/.bash_profile:
;;;
;;; SSH_AUTH_SOCK=$@{XDG_RUNTIME_DIR-$HOME/.cache@}/ssh-agent/socket
;;; export SSH_AUTH_SOCK
;;;
;;; Code:

(use-modules (shepherd support))

(define ssh-agent
  (make <service>
    #:provides '(ssh-agent)
    #:docstring "Run `ssh-agent'"
    #:start (lambda ()
              (let ((socket-dir (string-append %user-runtime-dir "/ssh-agent")))
                (unless (file-exists? socket-dir)
                  (mkdir-p socket-dir)
                  (chmod socket-dir #o700))
                (fork+exec-command
                 `("ssh-agent" "-D" "-a" ,(string-append socket-dir "/socket"))
                 #:log-file (string-append %user-log-dir "/ssh-agent.log"))))
    #:stop (make-kill-destructor)
    #:respawn? #t))

(register-services ssh-agent)
(start ssh-agent)
@end lisp

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node The root and unknown services
@section The @code{root} and @code{unknown} services

@cindex root service
@cindex special services
The service @code{root} is special, because it is used to control the
Shepherd itself.  It has an alias @code{shepherd}.  It provides the
following actions (in addition to @code{enable}, @code{disable} and
@code{restart} which do not make sense here).

@table @code
@item status
Displays which services are started and which ones are not.

@item detailed-status
Displays detailed information about every registered service.

@item load @var{file}
Evaluate the Scheme code in @var{file} in a fresh module that uses the
@code{(oop goops)} and @code{(shepherd services)} modules---as with the
@code{--config} option of @command{shepherd} (@pxref{Invoking shepherd}).

@item eval @var{exp}
Likewise, evaluate Scheme expression @var{exp} in a fresh module with
all the necessary bindings.

@item unload @var{service-name}
Attempt to remove the service identified by @var{service-name}.
@command{shepherd} will first stop the service, if necessary, and then
remove it from the list of registered services.  Any services
depending upon @var{service-name} will be stopped as part of this
process.

If @var{service-name} simply does not exist, output a warning and do
nothing.  If it exists, but is provided by several services, output a
warning and do nothing.  This latter case might occur for instance with
the fictional service @code{web-server}, which might be provided by both
@code{apache} and @code{nginx}.  If @var{service-name} is the special
string and @code{all}, attempt to remove all services except for the Shepherd
itself.

@item reload @var{file-name}
Unload all known optional services using unload's @code{all} option,
then load @var{file-name} using @code{load} functionality.  If
file-name does not exist or @code{load} encounters an error, you may
end up with no defined services.  As these can be reloaded at a later
stage this is not considered a problem.  If the @code{unload} stage
fails, @code{reload} will not attempt to load @var{file-name}.

@item daemonize
Fork and go into the background.  This should be called before
respawnable services are started, as otherwise we would not get the
@code{SIGCHLD} signals when they terminate.

@item enable-persistency
When terminating, save the list of running services in a file.
@c FIXME-CRITICAL: How can we specify which one?

@item disable-persistency
Don't save the list of running services when terminating.

@end table

@cindex unknown service
@cindex fallback service
The @code{unknown} service must be defined by the user and if it
exists, is used as a fallback whenever we try to invoke an unknown
action of an existing service or use a service that does not exist.
This is useful only in few cases, but enables you to do various sorts
of unusual things.

@c FIXME-CRITICAL: finish

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Misc Facilities
@chapter Misc Facilities

This is a list of facilities which are available to code running
inside of the Shepherd and is considered generally useful, but is not directly
related to one of the other topic covered in this manual.

@menu
* Errors::         Signalling, handling and ignoring errors.
* Communication::  Input/Output in various ways.
* Others::         Stuff that is useful, but is homeless.
@end menu

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Errors
@section Errors

@cindex assertions
@deffn {macro} assert expr
If @var{expr} yields @code{#f}, display an appropriate error
message and throw an @code{assertion-failed} exception.
@end deffn

@deffn {procedure} caught-error key args
Tell the Shepherd that a @var{key} error with @var{args} has occurred.  This is
the simplest way to cause caught error result in uniformly formatted
warning messages.  The current implementation is not very good,
though.
@end deffn

@cindex system errors
@deffn {macro} without-system-error expr@dots{}
Evaluates the @var{expr}s, not going further if a system error occurs,
but also doing nothing about it.
@end deffn

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Communication
@section Communication

The @code{(shepherd comm)} module provides primitives that allow clients such
as @command{herd} to connect to @command{shepherd} and send it commands to
control or change its behavior (@pxref{Slots of services, actions of
services}).

@tindex <shepherd-command>
Currently, clients may only send @dfn{commands}, represented by the
@code{<shepherd-command>} type.  Each command specifies a service it
applies to, an action name, a list of strings to be used as arguments,
and a working directory.  Commands are instantiated with
@code{shepherd-command}:

@deffn {procedure} shepherd-command @var{action} @var{service} @
         [#:@var{arguments} '()] [#:@var{directory} (getcwd)]
Return a new command (a @code{<shepherd-command>}) object for
@var{action} on @var{service}.
@end deffn

@noindent
Commands may then be written to or read from a communication channel
with the following procedures:

@deffn {procedure} write-command @var{command} @var{port}
Write @var{command} to @var{port}.
@end deffn

@deffn {procedure} read-command @var{port}
Receive a command from @var{port} and return it.
@end deffn

In practice, communication with @command{shepherd} takes place over a
Unix-domain socket, as discussed earlier (@pxref{Invoking shepherd}).
Clients may open a connection with the procedure below.

@deffn {procedure} open-connection [@var{file}]
Open a connection to the daemon, using the Unix-domain socket at
@var{file}, and return the socket.

When @var{file} is omitted, the default socket is used.
@end deffn

@cindex output
The daemon writes output to be logged or passed to the
currently-connected client using @code{local-output}:

@deffn {procedure} local-output format-string . args
This procedure should be used for all output operations in the Shepherd.  It
outputs the @var{args} according to the @var{format-string}, then
inserts a newline.  It writes to whatever is the main output target of
the Shepherd, which might be multiple at the same time in future versions.
@end deffn

@cindex protocol, between @command{shepherd} and its clients
Under the hood, @code{write-command} and @code{read-command} write/read
commands as s-expressions (sexps).  Each sexp is intelligible and
specifies a protocol version.  The idea is that users can write their
own clients rather than having to invoke @command{herd}.  For instance,
when you type @command{herd status}, what is sent over the wire is the
following sexp:

@lisp
(shepherd-command
  (version 0)
  (action status) (service root)
  (arguments ()) (directory "/data/src/dmd"))
@end lisp

The reply is also an sexp, along these lines:

@lisp
(reply (version 0)
       (result (((service @dots{}) @dots{})))
       (error #f) (messages ()))
@end lisp

This reply indicates that the @code{status} action was successful,
because @code{error} is @code{#f}, and gives a list of sexps denoting
the status of services as its @code{result}.  The @code{messages} field
is a possibly-empty list of strings meant to be displayed as is to the
user.


@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Others
@section Others

@cindex hashes
@deffn {procedure} copy-hashq-table table new-size
Create a hash-table with size @var{new-size}, and insert all values
from @var{table} into it, using @code{eq?} when inserting.  This
procedure is mainly used internally, but is a generally useful
utillity, so it can by used by everyone.
@end deffn

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Internals
@chapter Internals

This chapter contains information about the design and the
implementation details of the Shepherd for people who want to hack it.

The GNU@tie{}Shepherd is developed by a group of people in connection
with @uref{https://www.gnu.org/software/guix/, Guix System}, GNU's
advanced distribution, but it can be used on other distros as well.
You're very much welcome to join us!  You can report bugs to
@email{bug-guix@@gnu.org} and send patches or suggestions to
@email{guix-devel@@gnu.org}.

@menu
* Coding standards::    How to properly hack the Shepherd.
* Design decisions::    Why the Shepherd is what it is.
* Service Internals::   How services actually work.
@end menu

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Coding standards
@section Coding standards

About formatting: Use common sense and GNU Emacs (which actually is
the same, of course), and you almost can't get the formatting wrong.
Formatting should be as in Guile and Guix, basically.  @xref{Coding
Style,,, guix, GNU Guix Reference Manual}, for more info.

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Design decisions
@section Design decisions

@quotation Note
This section was written by Wolfgang Jährling back in 2003 and documents
the original design of what was then known as GNU@tie{}dmd.  The main
ideas remain valid but some implementation details and goals have
changed.
@end quotation

The general idea of a service manager that uses dependencies, similar
to those of a Makefile, came from the developers of the GNU Hurd, but
as few people are satisfied with System V Init, many other people had
the same idea independently.  Nevertheless, the Shepherd was written with the
goal of becoming a replacement for System V Init on GNU/Hurd, which
was one of the reasons for choosing the extension language of the GNU
project, Guile, for implementation (another reason being that it makes
it just so much easier).

The runlevel concept (i.e. thinking in @emph{groups} of services) is
sometimes useful, but often one also wants to operate on single
services.  System V Init makes this hard: While you can start and stop
a service, @code{init} will not know about it, and use the runlevel
configuration as its source of information, opening the door for
inconsistencies (which fortunately are not a practical problem
usually).  In the Shepherd, this was avoided by having a central entity that is
responsible for starting and stopping the services, which therefore
knows which services are actually started (if not completely
improperly used, but that is a requirement which is impossible to
avoid anyway).  While runlevels are not implemented yet, it is clear
that they will sit on top of the service concept, i.e. runlevels will
merely be an optional extension that the service concept does not rely
on.  This also makes changes in the runlevel design easier when it may
become necessary.

The consequence of having a daemon running that controls the services
is that we need another program as user interface which communicates
with the daemon.  Fortunately, this makes the commands necessary for
controlling services pretty short and intuitive, and gives the
additional bonus of adding some more flexibility.  For example, it is
easiely possible to grant password-protected control over certain
services to unprivileged users, if desired.

An essential aspect of the design of the Shepherd (which was already mentioned
above) is that it should always know exactly what is happening,
i.e. which services are started and stopped.  The alternative would
have been to not use a daemon, but to save the state on the file
system, again opening the door for inconsistencies of all sorts.
Also, we would have to use a separate program for respawning a service
(which just starts the services, waits until it terminates and then
starts it again).  Killing the program that does the respawning (but
not the service that is supposed to be respawned) would cause horrible
confusion.  My understanding of ``The Right Thing'' is that this
conceptionally limited strategy is exactly what we do not want.

The way dependencies work in the Shepherd took a while to mature, as it was not
easy to figure out what is appropriate.  I decided to not make it too
sophisticated by trying to guess what the user might want just to
theoretically fulfill the request we are processing.  If something
goes wrong, it is usually better to tell the user about the problem
and let her fix it, taking care to make finding solutions or
workarounds for problems (like a misconfigured service) easy.  This
way, the user is in control of what happens and we can keep the
implementation simple.  To make a long story short, @emph{we don't try
to be too clever}, which is usually a good idea in developing
software.

If you wonder why I was giving a ``misconfigured service'' as an
example above, consider the following situation, which actually is a
wonderful example for what was said in the previous paragraph: Service
X depends on symbol S, which is provided by both A and B.  A depends
on AA, B depends on BB.  AA and BB conflict with each other.  The
configuration of A contains an error, which will prevent it from
starting; no service is running, but we want to start X now.  In
resolving its dependencies, we first try to start A, which will cause
AA to be started.  After this is done, the attempt of starting A
fails, so we go on to B, but its dependency BB will fail to start
because it conflicts with the running service AA.  So we fail to
provide S, thus X cannot be started.  There are several possibilities
to deal with this:

@itemize @bullet
@item
When starting A fails, terminate those services which have been
started in order to fulfill its dependencies (directly and
indirectly).  In case AA was running already, we would not want to
terminate it.  Well, maybe we would, to avoid the conflict with BB.
But even if we would find out somehow that we need to terminate AA to
eventually start X, is the user aware of this and wants this to happen
(assuming AA was running already)?  Probably not, she very likely has
assumed that starting A succeeds and thus terminating AA is not
necessary.  Remember, unrelated (running) services might depend in AA.
Even if we ignore this issue, this strategy is not only complicated,
but also far from being perfect: Let's assume starting A succeeds, but
X also depends on a service Z, which requires BB.  In that case, we
would need to detect in the first place that we should not even try to
start A, but directly satisfy X's dependency on S with B.

@item
We could do it like stated above, but stop AA only if we know we won't
need it anymore (for resolving further dependencies), and start it
only when it does not conflict with anything that needs to get
started.  But should we stop it if it conflicts with something that
@emph{might} get started?  (We do not always know for sure what we
will start, as starting a service might fail and we want to fall back
to a service that also provides the particular required symbol in that
case.)  I think that either decision will be bad in one case or
another, even if this solution is already horribly complicated.

@item
When we are at it, we could just calculate a desired end-position, and
try to get there by starting (and stopping!) services, recalculating
what needs to be done whenever starting a service fails, also marking
that particular service as unstartable, except if it fails to start
because a dependency could not be resolved (or maybe even then?).
This is even more complicated.  Instead of implementing this and
thereby producing code that (a) nobody understands, (b) certainly has
a lot of bugs, (c) will be unmaintainable and (d) causes users to
panic because they won't understand what will happen, I decided to do
the following instead:

@item
Just report the error, and let the user fix it (in this case, fix the
configuration of A) or work around it (in this case, disable A so that
we won't start AA but directly go on to starting B).
@end itemize

I hope you can agree that the latter solution after all is the best
one, because we can be sure to not do something that the user does not
want us to do.  Software should not run amok.  This explanation was
very long, but I think it was necessary to justify why the Shepherd uses a very
primitive algorithm to resolve dependencies, despite the fact that it
could theoretically be a bit more clever in certain situations.

One might argue that it is possible to ask the user if the planned
actions are ok with her, and if the plan changes ask again, but
especially given that services are supposed to usually work, I see few
reasons to make the source code of the Shepherd more complicated than
necessary.  If you volunteer to write @emph{and} maintain a more
clever strategy (and volunteer to explain it to everyone who wants to
understand it), you are welcome to do so, of course@dots{}

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Service Internals
@section Service Internals

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node GNU Free Documentation License
@appendix GNU Free Documentation License

@include fdl-1.3.texi

@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@node Concept Index
@unnumbered Concept Index

@printindex cp

@node Procedure and Macro Index
@unnumbered Procedure and Macro Index

@printindex fn

@node Variable Index
@unnumbered Variable Index

@printindex vr

@node Type Index
@unnumbered Type Index

@printindex tp

@bye
